DSFX =
{
	util:
	{
		fix: function( obj, phunction )
		{
			var args = [].splice.call( arguments, 2 );
			return function()
			{
				phunction.apply( obj, [].concat.apply( args, arguments ) );
			}	
		},
		
		on: function( obj, phunction, _phunction )
		{
			var __phunction = obj[phunction];
			obj[phunction] = function()
			{
				var result = __phunction.apply( obj, arguments );
				_phunction.apply( null, arguments );
				return result;
			}
		},
	
		unit: function( string )
		{
			return string.slice( string.length - ( string.length - String( parseFloat( string ) ).length ) );
		},
		
		$: function( el )
		{
			if ( el.substr )
			{
				return document.getElementById( el );
			}
			return el;
		},
		
		ensureClass: function( el, className )
		{
			el = DSFX.util.$(el);
			if ( el.className.indexOf( className ) == -1 )
			{
				el.className += ( ' ' + className );
			}
		},
		
		futureStyles: function( el, classNames, overrides )
		{
			el = DSFX.util.$(el);
			var cache = 
			{
				styles: el.style,
				className: el.className
			};
			el.className = "";
			
			for ( var i=0, len=classNames.length; i<len; i++ )
			{
				DSFX.util.ensureClass( el, classNames[i] );
			}
				
			var futureStyles = DSFX.util.animatableStyles( DSFX.util.currentStyles( el ) );
		
			el.className = cache.className;
			
			return futureStyles;
		},
	
		currentStyles: function( el )
		{
			el = DSFX.util.$(el);
		    if ( el.currentStyle )
		    {
		        return el.currentStyle;
		    }
		    else if ( document.defaultView.getComputedStyle )
			{
		        return document.defaultView.getComputedStyle( el, null );
			}
		},
		
		animatableStyles: function( styles )
		{
			var animatable = {};
			
			for ( var style in styles )
			{
				if ( !isNaN( parseFloat( styles[style] ) )
				  && isNaN( styles[style] )
				)
				{
					animatable[ style ] = styles[ style ];
				}
			}
			return animatable;
		}
	}
};